package gestorvideoclub.jdbc;


import gestorvideoclub.jdbc.AccesoDatos;
import gestorvideoclub.Cliente;
import gestorvideoclub.Producto;
import gestorvideoclub.Reserva;
import gestorvideoclub.enumeraciones.*;
import gestorvideoclub.util.UtilFecha;
import java.sql.*;
import java.util.ArrayList;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import javax.management.timer.Timer;


public class ReservaJDBC{
    /**
     * Este método inserta una nueva reserva en nuestro sistema
     *
     */
    public static  void insertarReserva(Reserva reserva)
    {
        String sql = "insert into reservas (id_cliente, fechaReserva, fechaSms, fechaAlquiler, pendiente, maxDiasReserva, titulo, tipoProducto) ";
        sql += "values("+reserva.getCliente().getId();
        sql += ", '"+UtilFecha.fechaMySQL(reserva.getFechaReserva())+"', '"+UtilFecha.fechaMySQL(reserva.getFechaSMS())+"', '"+UtilFecha.fechaMySQL(reserva.getFechaAlquiler())+"' , "+reserva.getPendiente();
        sql +=", "+reserva.getMaxDiaReserva()+", '"+reserva.getTitulo()+"','"+reserva.getTipoProducto()+"')";

        //System.out.println(sql);
        Connection con = null;
        try{
            con = AccesoDatos.getConexion();
            Statement st = con.createStatement();
            st.executeUpdate(sql);
            st.close();
        }
        catch(Exception e){
            System.out.println("Error al insertar una reserva "+e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }
    }

    //TODO
    public static ArrayList obtenerReserva(Cliente cliente)
    {

        String sql = "select * from reservas where id_cliente = "+cliente.getId()+" and pendiente != 0";

        Connection con = null;
        Statement st = null;
        ResultSet rs = null;
        //System.out.println(sql);

        ArrayList listaReserva = new ArrayList();
        try{
            con = AccesoDatos.getConexion();
            st = con.createStatement();
            rs = st.executeQuery(sql);
            while(rs.next())
            {
                Reserva reserva = new Reserva();
                reserva.setIdReserva(rs.getInt("Id"));

                TipoProductoEnum tipo = TipoProductoEnum.valueOf(rs.getString("tipoProducto"));
                int idProducto = rs.getInt("id_producto");
                Producto producto;
                if(tipo.equals(TipoProductoEnum.BlueRay) || tipo.equals(TipoProductoEnum.DVD)){
                    producto = PeliculaJDBC.obtenerPeliculaPorId(idProducto);
                }
                else{
                    producto = VideojuegoJDBC.obtenerVideojuegoPorId(idProducto);
                }
                producto.setId(idProducto);
                reserva.setProducto(producto);

                reserva.setCliente(cliente);
                reserva.getCliente().setId(rs.getInt("id_cliente"));
                
                String tex = rs.getString("fechaReserva");
                reserva.setFechaReserva(UtilFecha.obtenerFechaBD(tex));

                tex = rs.getString("fechaSms");
                reserva.setFechaSMS(UtilFecha.obtenerFechaBD(tex));

                tex = rs.getString("fechaAlquiler");
                reserva.setFechaAlquiler(UtilFecha.obtenerFechaBD(tex));

                int pen = rs.getInt("pendiente");
                if(pen == 0){
                    reserva.setPendiente(false);
                }
                else{
                    reserva.setPendiente(true);
                }

                reserva.setMaxDiaReserva(rs.getInt("maxDiasReserva"));

                tex = rs.getString("tipoProducto");
                reserva.setTitulo(rs.getString("titulo"));
                reserva.setTipoProducto(TipoProductoEnum.valueOf(tex));
                listaReserva.add(reserva);
            }
            //System.out.println("tamaño :"+listaReserva.size());
            rs.close();
            st.close();

        }catch(Exception e){
            System.out.println("Error a obtener la/s reserva/s "+e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }
        return listaReserva;
    }

    
    // TODO
    public static Reserva obtenerDatosProductoReserva(Producto  producto)
    {
        String sql = "select  *  from reservas, productos where reservas.idProducto = productos.idProducto";
        sql += " and productos.codigo="+producto.getCodigo()+" order by idProducto";
        Connection con = AccesoDatos.getConexion();
        Reserva reserva = null;
        try{
            Statement st = con.createStatement();
            ResultSet rs = st.executeQuery(sql);
            rs.next();
                reserva.setIdReserva(rs.getInt("Id"));
                reserva.getCliente().setId(rs.getInt("idCliente"));
                reserva.setTitulo(rs.getString("titulo"));
                String tex = rs.getString("tipoProducto");
                reserva.setTipoProducto(TipoProductoEnum.valueOf(tex));
                Date dateAux = rs.getDate("fechaReserva");
                DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
                long dLong = dateAux.getTime();

        }
        catch(Exception e)
        {
            System.out.println("Error al obtener la reserva "+e.getMessage());
        }
        return null;
    }

    public static Reserva obtenerReservaPorProducto(Producto producto)
    {
        String sql = "select * from reservas ";
        sql += " where reservas.titulo = '"+producto.getTitulo()+"'";
        sql += " and reservas.tipoProducto = '"+producto.getTipo()+"'";
        sql += " and reservas.pendiente != 0 and reservas.fechaSms = '"+UtilFecha.fechaMySQL(new Date(0))+"' ";
        sql += "and reservas.fechaAlquiler = '"+UtilFecha.fechaMySQL(new Date(0))+"' order by reservas.Id asc limit 1";

        //System.out.println(sql);
        
        Reserva reserva = new Reserva();
        reserva.setProducto(producto);
        reserva.setCliente(new Cliente());
        Connection con = null;
        Statement st = null;
        ResultSet rs = null;
        try{
            con = AccesoDatos.getConexion();
            st = con.createStatement();
            rs = st.executeQuery(sql);
            if(rs.next()){
                reserva.setIdReserva(rs.getInt("reservas.Id"));
                reserva.setTitulo(rs.getString("titulo"));
                String aux = rs.getString("tipoProducto");

                reserva.setTipoProducto(TipoProductoEnum.valueOf(aux));
                reserva.getCliente().setId(rs.getInt("id_cliente"));
                aux = rs.getString("fechaReserva");

                reserva.setFechaReserva(UtilFecha.obtenerFechaBD(aux));

                aux = rs.getString("fechaSms");
                reserva.setFechaSMS(UtilFecha.obtenerFechaBD(aux));

                aux = rs.getString("fechaAlquiler");
                reserva.setFechaAlquiler(UtilFecha.obtenerFechaBD(aux));
            
                if(rs.getInt("pendiente") == 0){
                    reserva.setPendiente(false);
                }
                else{
                    reserva.setPendiente(true);
                }
                reserva.setMaxDiaReserva(rs.getInt("maxDiasReserva"));
            }
            rs.close();
            st.close();
        }
        catch(Exception e)
        {
            System.out.println("Error a obtener reserva del producto "+ e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }
        int idCliente = reserva.getCliente().getId();
        reserva.setCliente(ClienteJDBC.obtenerClientePorId(idCliente));
        return reserva;
    }

    /**
     * Este método da la posibilidad de modificar la fecha en que se envia el sms o la fecha de alquiler
     * y también si la reserva está pendiente o no
     * una reserva
     * @param reserva
     */
    public static void modificarReserva(Reserva reserva)
    {
        int pen = 1;
        if(!reserva.getPendiente())
        {
            pen = 0;
        }


        String sql ="update reservas set";
        sql += " reservas.id_producto ="+reserva.getProducto().getId();
        sql += ", reservas.fechaSms = '"+UtilFecha.fechaMySQL(reserva.getFechaSMS())+"'";
        sql += ", reservas.fechaAlquiler = '"+UtilFecha.fechaMySQL(reserva.getFechaAlquiler())+"'";
        sql += ", pendiente = "+pen;
        sql += " where Id ="+reserva.getIdReserva();

        //System.out.println(sql);
        Connection con = null;
        Statement st = null;
        try{
            con = AccesoDatos.getConexion();
            st = con.createStatement();
            st.executeUpdate(sql);
            st.close();
            System.out.println("La reserva se ha modificado correctamente");
        }
        catch(Exception e)
        {
            System.out.println("Error en la modificación de la reserva "+e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }
    }

    public static ArrayList<Reserva> obtenerReservasPendiente(){
        ArrayList<Reserva> lista = new ArrayList<Reserva>();

        String sql = "select * from reservas where reservas.fechaSms != '1970-01-01' and reservas.fechaAlquiler = '1970-01-01' ";
        sql +=" and reservas.pendiente != 0 and reservas.id_producto != 0";

        //System.out.println(sql);

        Connection con = null;
        Statement st = null;
        ResultSet rs = null;
        try{
            con = AccesoDatos.getConexion();
            st = con.createStatement();
            rs = st.executeQuery(sql);
            while(rs.next()){
                Reserva reserva = new Reserva();
                reserva.setCliente(new Cliente());
                reserva.setIdReserva(rs.getInt("Id"));
                int idProducto = rs.getInt("id_producto");
                Producto producto;
                TipoProductoEnum tipo = ProductoJDBC.obtenerTipoProductoPorId(idProducto);
                if(tipo.equals(TipoProductoEnum.BlueRay) || tipo.equals(TipoProductoEnum.DVD)){
                    producto = PeliculaJDBC.obtenerPeliculaPorId(idProducto);
                }else{
                    producto = VideojuegoJDBC.obtenerVideojuegoPorId(idProducto);
                }
                reserva.setProducto(producto);
                reserva.getProducto().setId(idProducto);
                
                reserva.getCliente().setId(rs.getInt("id_cliente"));
                reserva.setFechaReserva(UtilFecha.obtenerFechaBD(rs.getString("fechaReserva")));
                reserva.setFechaSMS(UtilFecha.obtenerFechaBD(rs.getString("fechaSms")));
                reserva.setFechaAlquiler(UtilFecha.obtenerFechaBD(rs.getString("fechaAlquiler")));
                if(rs.getInt("pendiente") == 0){
                    reserva.setPendiente(false);
                }
                else{
                    reserva.setPendiente(true);
                }
                reserva.setMaxDiaReserva(rs.getInt("maxDiasReserva"));
                reserva.setTitulo(rs.getString("titulo"));
                reserva.setTipoProducto(TipoProductoEnum.valueOf(rs.getString("tipoProducto")));
                lista.add(reserva);
            }
            //System.out.println("Tamaño de la lista"+lista.size());
            rs.close();
            st.close();
        }
        catch(Exception e){
            System.out.println("Error al obtener la lista de reservas pendientes "+e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }

        return lista;
    }


    public static void modificarEstadoProductoPorId(int idProducto, ProductoEnum estado)
    {
        String sql = "update productos set productos.estadoProducto ='"+estado+"' where productos.Id ="+idProducto;

        Connection con = null;
        Statement st = null;

        //System.out.println(sql);

        try{
            con = AccesoDatos.getConexion();
            st = con.createStatement();
            st.executeUpdate(sql);
            System.out.println("\nLa actualización se ha realizado correctamente");
            st.close();
        }
        catch(Exception e){
            System.out.println("Error al actualizar el estado de producto reservado "+e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }
    }

    public static ArrayList reservaParaAlquilar(Cliente cliente){
        String sql = "select * from reservas where id_cliente = "+cliente.getId()+" and pendiente != 0 and ";
        sql += "fechaSms != '1970-01-01' and fechaAlquiler = '1970-01-01'";

        //System.out.println(sql);
        ArrayList lista = new ArrayList();
        Connection con = null;
        Statement st = null;
        ResultSet rs = null;
        try{
            con = AccesoDatos.getConexion();
            st = con.createStatement();
            rs = st.executeQuery(sql);
            while(rs.next()){
                Reserva reserva = new Reserva();
                reserva.setIdReserva(rs.getInt("Id"));

                int idProducto = rs.getInt("id_producto");
                TipoProductoEnum tipo = TipoProductoEnum.valueOf(rs.getString("tipoProducto"));
                Producto producto;
                if(tipo.equals(TipoProductoEnum.DVD) || tipo.equals(TipoProductoEnum.BlueRay)){
                    producto = PeliculaJDBC.obtenerPeliculaPorId(idProducto);
                }
                else{
                    producto = VideojuegoJDBC.obtenerVideojuegoPorId(idProducto);
                }

                reserva.setProducto(producto);

                reserva.setCliente(cliente);

                String tex = rs.getString("fechaReserva");
                reserva.setFechaReserva(UtilFecha.obtenerFechaBD(tex));

                tex = rs.getString("fechaSms");
                reserva.setFechaSMS(UtilFecha.obtenerFechaBD(tex));

                tex = rs.getString("fechaAlquiler");
                reserva.setFechaAlquiler(UtilFecha.obtenerFechaBD(tex));

                int pen = rs.getInt("pendiente");
                if(pen == 0){
                    reserva.setPendiente(false);
                }
                else{
                    reserva.setPendiente(true);
                }
                reserva.setMaxDiaReserva(rs.getInt("maxDiasReserva"));
                reserva.setTitulo(rs.getString("titulo"));
                reserva.setTipoProducto(tipo);//Obtenido para producto
                lista.add(reserva);
            }

        }
        catch(Exception e){
            System.out.println("[!] Error al obtener las reservas listas para reservar "+e.getMessage());
        }
        finally{
            AccesoDatos.cerrarConexion(con);
        }

        return lista;
    }
}
